﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace cache_control
{
    public partial class main_Form : Form
    {

        public int[] cacheState = new int[4];// cache状态:0 无效 １共享 ２ 独占
        String[,] Mem_Content = new string[10, 9]{ { "0", "", "", "10", "", "", "20", "", "" },
            { "1", "", "", "11", "", "", "21", "", "" }, { "2", "", "", "12", "", "", "22", "", "" },
            { "3", "", "", "13", "", "", "23", "", "" }, { "4", "", "", "14", "", "", "24", "", "" },
            { "5", "", "", "15", "", "", "25", "", "" }, { "6", "", "", "16", "", "", "26", "", "" },
            { "7", "", "", "17", "", "", "27", "", "" }, { "8", "", "", "18", "", "", "28", "", "" },
            { "9", "", "", "19", "", "", "29", "", "" } };
        struct Mem
        {
            public int num;    //块号
            public string status;   //当前状态
            List<int> catalogue;  //存放目录表的list
        }

        struct block
        {
            public int num; //编号
            public string status;   //当前状态
            public int addr;    //对应的memory中的地址

        };

        public main_Form()
        {
            InitializeComponent();
        }
        private void main_Form_Load(object sender, EventArgs e)
        {           
            cache_initialize(); //cache的初始化
            mem_initialize(0);//mem的初始化
            combox_initialize();    //下拉框的初始化
            comboBox5.SelectedIndex = 0;    //设置默认为目录模式，0为目录模式，1为监听模式

        }

        public void cache_initialize()  //cache界面初始化
        {
            //cache的目录生成
            for (int i = 1; i <= 4; i++)
            {
                get_cache_listview(i).Columns.Add("Cache", 80, HorizontalAlignment.Left).DisplayIndex = 0;
                get_cache_listview(i).Columns.Add("状态", 80, HorizontalAlignment.Left).DisplayIndex = 1;
                get_cache_listview(i).Columns.Add("目标地址", 80, HorizontalAlignment.Left).DisplayIndex = 2;
            }
            int cache_size = 4;
            //cache块的初始化
            for (int i = 0; i < cache_size; i++)
                for (int j = 1; j <= 4; j++)
                {
                    ListViewItem lv = new ListViewItem();
                    lv.Text = i.ToString();
                    lv.SubItems.Add(" ");
                    lv.SubItems.Add(" ");
                    get_cache_listview(j).Items.Add(lv);
                }
        }

        public void mem_initialize(int model)    //mem界面初始化
        {
            //mem的目录生成
            String[] memory_items = new String[4] { "Memory1", "Memory2", "Menory3", "Memory4" };
            for (int i = 1; i <= 4; i++)
            {
                get_Mem_listview(i).Columns.Add(memory_items[i-1], 80, HorizontalAlignment.Left).DisplayIndex = 0;
                if (model == 0)
                {
                    get_Mem_listview(i).Columns.Add("状态", 80, HorizontalAlignment.Left).DisplayIndex = 1;
                    get_Mem_listview(i).Columns.Add("目标地址", 80, HorizontalAlignment.Left).DisplayIndex = 2;
                }
            }
            //mem的初始化值
            int memory_length = 10; //设置memory大小为10*4
            for (int i = 0; i < memory_length; i++)
                for (int j = 1; j <= 4; j++)
                {
                    ListViewItem lv = new ListViewItem();
                    lv.Text = (i + j * memory_length - memory_length).ToString();
                    if (model==0)
                    {
                        lv.SubItems.Add(" ");
                        lv.SubItems.Add(" ");
                    }
                    get_Mem_listview(j).Items.Add(lv);
                }
        }

        public void clear_mem() //清空mem
        {
            listView5.Clear();
            listView6.Clear();
            listView7.Clear();
            listView8.Clear();
        }

        public void combox_initialize() //下拉框的初始化
        {
            String[] operate = new string[2] { "读", "写" };
            string[] model = new string[2] { "目录", "监听" };
            for (int i = 0; i < 2; i++) //添加combox的读，写选项
            {
                comboBox1.Items.Add(operate[i]);
                comboBox2.Items.Add(operate[i]);
                comboBox3.Items.Add(operate[i]);
                comboBox4.Items.Add(operate[i]);
                comboBox5.Items.Add(model[i]);
            }
        }

        public void cache_reset()
        {
            for (int i = 0; i < 4; i++)
                for (int j = 1; j <= 2; j++)
                    for (int k = 1; k < 5; k++)
                        get_cache_listview(k).Items[i].SubItems[j].Text = " ";
        }

        public void mem_reset()
        {
            for (int i = 0; i < 10; i++)
                for (int j = 1; j < 3; j++)
                    for (int k = 1; k <= 4; k++)
                        get_Mem_listview(k).Items[i].SubItems[j].Text = " ";
        }
        public int Is_hit(ListView listView, int num)   //判断是否命中
        {
            int tempory;
            for (int i = 0; i < 4; i++)
            {
                if (int.TryParse(listView.Items[i].SubItems[2].Text, out tempory) && tempory == num)
                    return i;   //命中时返回时哪一行
            }
            return -1;  //未命中就返回-1
        }



        public void read(ListView cache, int num)   //进行读操作
        {
            int k = num % 4;
            int num_men = num / 10 + 1;//判断该读写的位置在第几个memroy
            if (comboBox5.Text == "目录")
            {
                catalog_change_cache(cache, "共享", num);
                catalog_change_Mem(cache, get_Mem_listview(num_men), "共享", num);           
            }
            else
            {
                monitor_change_cache(cache, "共享", num);
            }
        }

        public void write(ListView cache, int num)   //进行写操作
        {
            int k = num % 4;
            int num_men = num / 10 + 1;//判断该读写的位置在第几个memroy
            if (comboBox5.Text == "目录")
            {
                catalog_change_cache(cache, "独占", num);
                catalog_change_Mem(cache, get_Mem_listview(num_men), "独占", num);
            }
            else
            {
                monitor_change_cache(cache, "独占", num);
            }
        }

        public void catalog_change_cache(ListView cache, string str, int num) //目录模式下修改cache
        {

            if (cache.Items[num % 4].SubItems[1].Text == "共享")  //cache块为共享
            {
                
                int k = int.Parse(cache.Items[num % 4].SubItems[2].Text);   //得到cache里存放的数字
                //MessageBox.Show("删除前的状态：",get_Mem_listview(k / 10 + 1).Items[k % 10].SubItems[2].Text);
                //MessageBox.Show("要被删除的块:",cache.Items[num % 4].SubItems[2].Text);
                get_Mem_listview(k / 10 + 1).Items[k % 10].SubItems[2].Text=get_Mem_listview(k / 10 + 1).Items[k % 10].SubItems[2].Text.Replace((Get_num_cache(cache)).ToString(),"");
                //MessageBox.Show("删除后长度为:",get_Mem_listview(k / 10 + 1).Items[k % 10].SubItems[2].Text.Length.ToString());
                if (get_Mem_listview(k / 10 + 1).Items[k % 10].SubItems[2].Text == "")
                {
                    get_Mem_listview(k / 10 + 1).Items[k % 10].SubItems[2].Text = " ";
                    get_Mem_listview(k / 10 + 1).Items[k % 10].SubItems[1].Text = " ";
                }
                     
            }
            else if (cache.Items[num % 4].SubItems[1].Text == "独占")
            {
                int k = int.Parse(cache.Items[num % 4].SubItems[2].Text);
                get_Mem_listview(k / 10 + 1).Items[k % 10].SubItems[1].Text = " ";
                get_Mem_listview(k / 10 + 1).Items[k % 10].SubItems[2].Text = " ";
            }
            cache.Items[num % 4].SubItems[1].Text = str;
            cache.Items[num % 4].SubItems[2].Text = num.ToString();

        }

        public void catalog_change_Mem(ListView cache, ListView Mem, string str, int num) //目录模式下改写memory
        {
            string num_cache = Get_num_cache(cache);   //cache的编号
            int row = num % 4;
            if (str == "共享")
            {
                if (Mem.Items[num % 10].SubItems[1].Text == "共享")
                {
                    if(Mem.Items[num % 10].SubItems[2].Text.IndexOf(num_cache)<=-1)
                        Mem.Items[num % 10].SubItems[2].Text += num_cache;
                    Mem.Items[num % 10].SubItems[1].Text = str; //将mem的目录表标记为共享
                }
                else if (Mem.Items[num % 10].SubItems[1].Text == "独占")
                {
                    //先将独占写回
                    get_cache_listview(int.Parse(Mem.Items[num % 10].SubItems[2].Text)).Items[row].SubItems[1].Text = "共享";
                    //然后在原先的后面加上自己cache的标签
                    Mem.Items[num % 10].SubItems[2].Text += num_cache;
                    Mem.Items[num % 10].SubItems[1].Text = str; //将mem的目录表标记为共享

                }
                else
                {
                    Mem.Items[num % 10].SubItems[2].Text =num_cache;    //与上面的共享不同在于这里为=而上面为+=
                    Mem.Items[num % 10].SubItems[1].Text = str; //将mem的目录表标记为共享
                }
            }
            else//独占的情况
            {
                if (Mem.Items[num % 10].SubItems[1].Text == "共享")
                {
                    int length = Mem.Items[num % 10].SubItems[2].Text.Length;
                    //MessageBox.Show(length.ToString());
                    for (int i = 0; i < length; i++)   //分次取消目录表里的数据的共享状态，失效
                    {
                        //MessageBox.Show(Mem.Items[num % 10].SubItems[2].Text.Substring(1, 1));
                        get_cache_listview(int.Parse(Mem.Items[num % 10].SubItems[2].Text.Substring(i, 1))).Items[row].SubItems[1].Text = " ";
                        get_cache_listview(int.Parse(Mem.Items[num % 10].SubItems[2].Text.Substring(i, 1))).Items[row].SubItems[2].Text = " ";
                    }

                    Mem.Items[num % 10].SubItems[1].Text = str; //将mem的目录表标记为独占
                    Mem.Items[num % 10].SubItems[2].Text = num_cache;   //目录表修改为只有独占的cache标签，其他的被清除
                }
                else if (Mem.Items[num % 10].SubItems[1].Text == "独占")
                {
                    //原先的独占写回，然后替换cache
                    get_cache_listview(int.Parse(Mem.Items[num % 10].SubItems[2].Text)).Items[row].SubItems[1].Text = " ";
                    get_cache_listview(int.Parse(Mem.Items[num % 10].SubItems[2].Text)).Items[row].SubItems[2].Text = " ";
                    Mem.Items[num % 10].SubItems[1].Text = str; //将mem的目录表标记为独占
                    Mem.Items[num % 10].SubItems[2].Text = num_cache;
                }
                else
                {
                    Mem.Items[num % 10].SubItems[1].Text = str; //将mem的目录表标记为独占
                    Mem.Items[num % 10].SubItems[2].Text = num_cache;   //添加cache标记
                }
            }
        }

        public void monitor_change_cache(ListView cache,string str,int num) //监听模式下cache的修改
        {
            string num_cache = Get_num_cache(cache);   //cache的编号
            int row = num % 4;
            if (str == "共享")
            {
                for (int i = 1; i <= 4; i++)//遍历每一个cache，检查是否有一样的
                {
                    int tem;
                    bool ok = int.TryParse(get_cache_listview(i).Items[num % 4].SubItems[2].Text, out tem);
                    if (ok && tem == num&& get_cache_listview(i).Items[num % 4].SubItems[1].Text=="独占")
                    {
                        get_cache_listview(i).Items[num % 4].SubItems[1].Text = "共享";
                        get_cache_listview(i).Items[num % 4].SubItems[2].Text =num.ToString();
                    }
                }
                cache.Items[num % 4].SubItems[1].Text = str;
                cache.Items[num % 4].SubItems[2].Text = num.ToString();
            }
            else
            {
                for (int i = 1; i <= 4; i++)//遍历每一个cache，检查是否有一样的
                {
                    int tem;
                    bool ok = int.TryParse(get_cache_listview(i).Items[num % 4].SubItems[2].Text,out tem);
                    if(ok && tem == num)
                    {
                        get_cache_listview(i).Items[num % 4].SubItems[1].Text = " ";
                        get_cache_listview(i).Items[num % 4].SubItems[2].Text = " ";
                    }
                }
                cache.Items[num % 4].SubItems[1].Text = str;
                cache.Items[num % 4].SubItems[2].Text = num.ToString();

            }
        }



        public string Get_num_cache(ListView listView)  //获取cache的宿主编号，这里保存为string类型，如果找不到就返回-1
        {
            if (listView == listView1)
                return "1";
            else if (listView == listView2)
                return "2";
            else if (listView == listView3)
                return "3";
            else if (listView == listView4)
                return "4";
            else
                return "-1";
        }
        public ListView get_cache_listview(int num)
        {
            if (num == 1)
                return listView1;
            else if (num == 2)
                return listView2;
            else if (num == 3)
                return listView3;
            else
                return listView4;
        }

        public ListView get_Mem_listview(int num)  
        {
            if (num == 1)
                return listView5;
            else if (num == 2)
                return listView6;
            else if (num == 3)
                return listView7;
            else
                return listView8;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            int addr;
            bool ok = int.TryParse(textBox1.Text,out addr);
            if (ok)
            {
                if (comboBox1.Text == "读")
                {
                    read(listView1, addr);
                }
                else if (comboBox1.Text == "写")
                {
                    write(listView1, addr);
                }  
            }
            textBox1.Text = "";
        }

        private void button2_Click(object sender, EventArgs e)
        {
            int addr;
            bool ok = int.TryParse(textBox2.Text, out addr);
            if (ok)
            {
                if (comboBox2.Text == "读")
                {
                    read(listView2, addr);
                }
                else if (comboBox2.Text == "写")
                {
                    write(listView2, addr);
                }
            }
            textBox2.Text = "";
        }

        private void button3_Click(object sender, EventArgs e)
        {
            int addr;
            bool ok = int.TryParse(textBox3.Text, out addr);
            if (ok)
            {
                if (comboBox3.Text == "读")
                {
                    read(listView3, addr);
                }
                else if (comboBox3.Text == "写")
                {
                    write(listView3, addr);
                }
            }
            textBox3.Text = "";
        }
        private void button4_Click(object sender, EventArgs e) 
        {
            int addr;
            bool ok = int.TryParse(textBox4.Text, out addr);
            if (ok)
            {
                if (comboBox4.Text == "读")
                {
                    read(listView4, addr);
                }
                else if (comboBox4.Text == "写")
                {
                    write(listView4, addr);
                }
            }
            textBox4.Text = "";
        }
        private void button5_Click(object sender, EventArgs e)  //复位
        {
            //所有数据清空为" "状态
            cache_reset();
            mem_reset();   
        }

        private void button6_Click(object sender, EventArgs e)
        {
            if (comboBox5.Text== "监听")
            {
                cache_reset();  //cache清空
                clear_mem();
                mem_initialize(1);//mem的初始化
            }
            else
            {
                cache_reset();  //cache清空
                clear_mem();
                mem_initialize(0);//mem的初始化
            }
        }
    }
}
